use gtk::glib::{self, object::ObjectExt};

#[derive(Debug, Default)]
enum ItemDeletionStatus {
    #[default]
    Standby,
    Confirm,
}

impl ItemDeletionStatus {
    fn icon_name(&self) -> &'static str {
        match self {
            ItemDeletionStatus::Standby => "cross-small-symbolic",
            ItemDeletionStatus::Confirm => "trash-symbolic",
        }
    }
}

glib::wrapper! {
    pub struct RecordDeletionButton(ObjectSubclass<imp::RecordDeletionButton>)
        @extends adw::Bin, gtk::Widget,
        @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
}

impl RecordDeletionButton {
    pub fn new() -> Self {
        glib::Object::new::<Self>()
    }

    // pub fn connect_delete<F>(&self, callback: F) -> glib::SignalHandlerId
    // where
    //     F: Fn() + 'static + Sync + Send,
    // {
    //     self.connect_closure("delete", false, glib::closure!(move || callback()))
    // }

    // pub fn connect_confirm_delete<F>(&self, callback: F) -> glib::SignalHandlerId
    // where
    //     F: Fn() + 'static,
    // {
    //     self.connect_closure("confirm-delete", false, glib::closure_local!(|| callback()))
    // }
}

impl Default for RecordDeletionButton {
    fn default() -> Self {
        Self::new()
    }
}

mod imp {
    use std::sync::{Arc, Mutex, OnceLock};

    use adw::subclass::prelude::ObjectSubclassExt;
    use adw::{prelude::BinExt, subclass::bin::BinImpl};
    use gtk::{
        glib::{self, object::ObjectExt, subclass::Signal},
        prelude::{StaticType, WidgetExt},
        subclass::{
            prelude::{ObjectImpl, ObjectImplExt, ObjectSubclass},
            widget::WidgetImpl,
        },
    };

    use crate::ui::record_deletion_button::ItemDeletionStatus;

    #[derive(Default)]
    pub struct RecordDeletionButton {
        pub(super) status: Arc<Mutex<ItemDeletionStatus>>,
        pub(super) icon: gtk::Image,
        pub(super) gesture: gtk::GestureClick,
    }

    #[glib::object_subclass]
    impl ObjectSubclass for RecordDeletionButton {
        const NAME: &'static str = "RecordDeletionButton";
        type Type = super::RecordDeletionButton;
        type ParentType = adw::Bin;
    }

    impl ObjectImpl for RecordDeletionButton {
        fn signals() -> &'static [glib::subclass::Signal] {
            static SIGNALS: OnceLock<Vec<Signal>> = OnceLock::new();
            SIGNALS.get_or_init(|| {
                vec![
                    Signal::builder("delete").build(),
                    Signal::builder("confirm-delete").build(),
                    Signal::builder("cancel-delete").build(),
                ]
            })
        }

        fn constructed(&self) {
            self.parent_constructed();

            let obj = self.obj();
            obj.set_child(Some(&self.icon));
            obj.add_controller(self.gesture.clone());

            self.icon
                .set_icon_name(Some(self.status.lock().unwrap().icon_name()));

            self.icon.set_margin_start(6);
            self.icon.set_margin_end(6);

            let status = self.status.clone();
            let self_icon = self.icon.clone();

            self.gesture.connect_pressed(glib::clone!(
                #[weak]
                obj,
                move |_, _, _, _| {
                    let mut current_status = status.lock().unwrap();
                    match *current_status {
                        ItemDeletionStatus::Standby => {
                            log::info!("Deletion button clicked. Waiting for confirmation.");
                            *current_status = ItemDeletionStatus::Confirm;
                            self_icon.set_icon_name(Some(current_status.icon_name()));
                            obj.emit_by_name::<()>("delete", &[]);
                        }
                        ItemDeletionStatus::Confirm => {
                            log::info!("Deletion button clicked. Confirmed to delete.");
                            obj.emit_by_name::<()>("confirm-delete", &[]);
                        }
                    }
                }
            ));
        }
    }

    impl WidgetImpl for RecordDeletionButton {}
    impl BinImpl for RecordDeletionButton {}
}
